/*********************************************************************************
 *      Copyright:  (C) 2021 iot
 *                  All rights reserved.
 *
 *       Filename:  conf.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0
 *         Author:  mk
 *                 
 ********************************************************************************/
#include <stdio.h>
#include "conf.h"
#include "../lib/iniparser.h"
#include "../lib/dictionary.h"
#include "../lib/logger.h"


int parser_conf(const char *conf_file, all_ctx_t *ctx, int debug)
{
    dictionary             *ini;

    light_ctx_t            *light_ctx;
    mqtt_ctx_t             *mqtt_ctx;
    
    log_ctx_t              *log_ctx;
    static logger_t        logger;

    const char             *str; 
    int                    val;

    if( !conf_file || !ctx )
    {
        fprintf(stderr, "ERROR: parser configure file or ctx is NULL\n");
        return 0;
    }

    memset(ctx, 0, sizeof(*ctx));

    log_ctx = &ctx->log_ctx;
    light_ctx = &ctx->light_ctx;
    mqtt_ctx = &ctx->mqtt_ctx;

    ini = iniparser_load(conf_file);
    if(!ini)
    {   
        fprintf(stderr, "ERROR: cannot parse file: '%s'\n", conf_file);
        return -1; 
    }   


    /* +------------------------------------------------------+
      *|    parser logger settings and start logger system    |
      *+------------------------------------------------------+*/
    if( !debug )
    {
        str = iniparser_getstring(ini, "logger:file", "/tmp/mqttd.log");
        strncpy(log_ctx->logfile, str, sizeof(log_ctx->logfile));
        log_ctx->logsize = iniparser_getint(ini, "logger:size", 1024);
        log_ctx->loglevel = iniparser_getint(ini, "logger:level", LOG_LEVEL_DEBUG);
    }
    else
    {
        strncpy(log_ctx->logfile, DBG_LOG_FILE, sizeof(log_ctx->logfile));
        log_ctx->loglevel = LOG_LEVEL_DEBUG;
        log_ctx->logsize = 1024;
    }

    if( logger_init(&logger, log_ctx->logfile, log_ctx->loglevel, log_ctx->logsize) < 0 || logger_open()<0 )
    {
        fprintf(stderr, "Logger system initialise failure\n");
        return -2;
    }

    log_nrml("Logger system initialise ok\n");


    /* +---------------------------------------------------------------+*
     **|                    parser production ID                       |*
     **+---------------------------------------------------------------+**/
    if( !(str=iniparser_getstring(ini, "common:id", NULL)) ) 
    {   
        log_err("ERROR: inipaeser pruduct ID failure!\n");
        return -2; 
    }   

    /*  cJSON parser ID will get  */
     strncpy(mqtt_ctx->id, str, sizeof(mqtt_ctx->id));
     log_nrml("parser pruduct ID [%s]\n", mqtt_ctx->id);

    /* +---------------------------------------------------------------+*
     **|          parser hardware module configuration ID              |*
     **+---------------------------------------------------------------+**/

    /*  relay control light */
    if( !(str=iniparser_getstring(ini, "hardware:led_pin", NULL)) )
    {
        log_err("ERROR: iniparser hardware: relay_pin failure\n ");
        return -2;
    }
    else
    {
        char             *ptr;
        int               i;

        ptr = strtok(str, ",");
        if( NULL == ptr )
        {
            log_nrml("relay pins format failure, can not find ',' in it.\n");
            return -2;
        }

        light_ctx->light_cnt = 1; 
        light_ctx->light_pins[0] = atoi(ptr);/* light_pins[LIGHT_MAX]*/ 

        for(i=0; i<LIGHT_MAX; i++)
        {
            ptr = strtok(NULL, ",");
            if( NULL != ptr)
            {
                light_ctx->light_pins[i+1] = atoi(ptr);
                light_ctx->light_cnt ++;

            }
        }
    }

    /*set lux_threshold for light*/
    light_ctx->lux_threshold = iniparser_getdouble(ini, "hardware:lux_threshold", 0.1);
    log_nrml("Parser fill-in light threshold lux [%.03f]\n", light_ctx->lux_threshold);

    /*set infrared */
    light_ctx->infrared_pin=iniparser_getint(ini, "hardware:infrared_pin", 0);
    log_nrml("Parser infrared pin connected BCM #pin number [%d]\n", light_ctx->infrared_pin);

    /*set light_intval */
    light_ctx->light_intval = iniparser_getint(ini, "hardware:light_intval", 20);
    log_nrml("Parser inbreak fill-in light interval time [%d]\n", light_ctx->light_intval);


    /* +---------------------------------------------------------------+*
     **|                    parser broker settings                     |*
     **+---------------------------------------------------------------+*/

    if( !(str=iniparser_getstring(ini, "broker:hostname", NULL)) )
    {   
        log_err("ERROR: iniparser broker server hostname failure\n");
        return -2; 
    }   

    strncpy(mqtt_ctx->host, str, sizeof(mqtt_ctx->host));

    if((val=iniparser_getint(ini, "broker:port", -1)) < 0)
    {   
        log_err("ERROR: iniparser broker server port failurei\n");
        return -2; 
    }   
    mqtt_ctx->port = val;
    log_nrml("parser broker server [ %s : %d ]\n", mqtt_ctx->host, mqtt_ctx->port);

    str=iniparser_getstring(ini, "broker:username", NULL);
    strncpy(mqtt_ctx->uid, str, sizeof(mqtt_ctx->uid));

    str=iniparser_getstring(ini, "broker:password", NULL);
    strncpy(mqtt_ctx->pwd, str, sizeof(mqtt_ctx->pwd));
    log_nrml("parser broker author by [%s : %s]\n", mqtt_ctx->uid, mqtt_ctx->pwd);

    val=iniparser_getint(ini, "broker:keepalive", 30);
    mqtt_ctx->keepalive = val;
    log_nrml("parser broker keepalive timeout[%d] seconds\n", mqtt_ctx->keepalive);
   

    /* +---------------------------------------------------------------+*
     **|               parser subscriber settings                      |*
     **+---------------------------------------------------------------+*/

    if( !(str=iniparser_getstring(ini, "subsciber:subTopic_ack", NULL)) )
    {
        log_err("ERROR: Parser MQTT subscriber topic_ack failure\n");
        return -2;
    }
    strncpy(mqtt_ctx->subTopic_ack, str, sizeof(mqtt_ctx->subTopic_ack) );

    if( !(str=iniparser_getstring(ini, "subsciber:subTopic_led", NULL)) )
    {   
        log_err("ERROR: Parser MQTT subscriber topic_led failure\n");
        return -2; 
    }   
    strncpy(mqtt_ctx->subTopic_led, str, sizeof(mqtt_ctx->subTopic_led) );

    val = iniparser_getint(ini, "subsciber:subQos", 0);
    mqtt_ctx->subQos = val;
    log_nrml("Parser subscriber topic \"%s\" and \"%s\"with Qos[%d]\n", mqtt_ctx->subTopic_ack, mqtt_ctx->subTopic_led, mqtt_ctx->subQos);


    /*+---------------------------------------------------------------+*
    **|               parser publish settings                         |*
    **+---------------------------------------------------------------+*/
    if(!(str=iniparser_getstring(ini, "publisher:pubTopic_reg", NULL)) )
    {
        log_err("ERROR: Parser MQTT publisher topic failure\n");
        return -2;
    }
    strncpy(mqtt_ctx->pubTopic_reg, str, sizeof(mqtt_ctx->pubTopic_reg) );

    if(!(str=iniparser_getstring(ini, "publisher:pubTopic_temp", NULL)) )
    {       
        log_err("ERROR: Parser MQTT publisher topic failure\n");
        return -2;
    }       
    strncpy(mqtt_ctx->pubTopic_temp, str, sizeof(mqtt_ctx->pubTopic_temp) );

    val = iniparser_getint(ini, "publisher:pubQos", 0);
    mqtt_ctx->pubQos = val;

    log_nrml("Parser publisher topic \"%s\" and \"%s\" with Qos[%d]\n", mqtt_ctx->pubTopic_reg, mqtt_ctx->pubTopic_temp,  mqtt_ctx->pubQos);

    val = iniparser_getint(ini, "publisher:interval", 0);
    mqtt_ctx->interval = val;
    log_nrml("Parser punlisher temperature interval is [%d]\n", mqtt_ctx->interval);


    return 0;
}


